package cc.rengu.igas.bomp.core.realize.impl;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.dao.BompUserRoleInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.BompUserRoleInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.UserRoleInfo;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.core.model.UserSessionInfo;
import cc.rengu.igas.bomp.core.realize.BspsPublicService;
import cc.rengu.igas.bomp.core.realize.UserPermissionCheckService;
import cc.rengu.igas.share.core.model.MchntBindInfo;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.util.List;

/**
 * 用户权限检查.
 */
public class UserPermissionCheckServiceImpl implements UserPermissionCheckService {

    RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    /**
     * 进行用户权限检查
     *
     * @param instId  机构号
     * @param userId  用户信息
     * @param mchntNo 商户号
     * @param txnNum  交易类型
     * @return 结果
     * @throws Exception 异常
     */
    @Override
    public boolean checkNormalUserPermission(String instId, String userId, String mchntNo, String txnNum, String appType) throws Exception {

        if (StringUtil.isEmptyOrNull(userId)
                || StringUtil.isEmptyOrNull(mchntNo)
                || StringUtil.isEmptyOrNull(txnNum)) {
            rglog.error("校验用户权限失败，参数为空，checkNormalUserPermission");
            throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
        }

        String key = userId + mchntNo;

        MchntBindInfo mchntBindInfo = JSON.parseObject(RedisUtil.onceGet(key), MchntBindInfo.class);
        if (null == mchntBindInfo) {
            BspsPublicService bspsPublicService = new BspsPublicServiceImpl();
            List<MchntBindInfo> mchntBindInfoList = bspsPublicService.getMchntBindInfo(instId, userId, mchntNo);
            if (null == mchntBindInfoList || mchntBindInfoList.isEmpty()) {
                rglog.info("该用户没有该商户绑定信息，userId:<{}>,mchntNo:<{}>", userId, mchntNo);
                throw new BizException(RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespDesc());
            }
            mchntBindInfo = mchntBindInfoList.get(0);
            RedisUtil.onceSet(key, JSON.toJSONString(mchntBindInfo));
        }

        String userRoleType = mchntBindInfo.getBindUserRole();

        BompUserRoleInfoMapper bompUserRoleInfoMapper = new BompUserRoleInfoMapperImpl();
        UserRoleInfo userRoleInfo = bompUserRoleInfoMapper.selectBompUserRoleInfoByRoleTypeAndTxnNum(instId, userRoleType, txnNum, appType);
        if (null == userRoleInfo) {
            rglog.info("该用户无该交易权限，userId:<{}>,mchntNo:<{}>,txnNum:<{}>", userId, mchntNo, txnNum);
            throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
        }

        return true;
    }

    /**
     * 检查拓展经理权限
     *
     * @param userInfo 用户信息
     * @param txnNum   交易码
     * @return 结果
     * @throws Exception 异常
     */
    @Override
    public boolean checkManagerUserPermission(UserInfo userInfo, String txnNum, String appType) throws Exception {
        if (null == userInfo || StringUtil.isEmptyOrNull(txnNum)) {
            rglog.info("校验用户权限失败，参数为空");
            return false;
        }

        //TODO 查询拓展经理信息表获取角色类型
        String userRoleType = "";

        return true;
    }


    @Override
    public UserSessionInfo checkSessionStatus(String instId, String sessionId) throws Exception {
        String userSessionInfo = RedisUtil.onceGet(sessionId);
        if (StringUtil.isEmptyOrNull(userSessionInfo)) {
            rglog.error("会话超时，sessionId:<{}>", sessionId);
            throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
        } else {
            RedisUtil.onceExpire(sessionId, BompAppParamConstant.SESSION_EFFECTIVE_TIME);
            rglog.info("当前会话有效，重置会话有效时长。sessionId:<{}>,sessionExpiryTime:<{}>", sessionId, BompAppParamConstant.SESSION_EFFECTIVE_TIME);
            return JSON.parseObject(userSessionInfo, UserSessionInfo.class);
        }
    }

    @Override
    public UserSessionInfo checkUserLoginSessionStatus(String instId, String sessionId, String userId) throws Exception {
        String sessionInfo = RedisUtil.onceGet(sessionId);
        if (StringUtil.isEmptyOrNull(sessionInfo)) {
            rglog.info("会话超时，sessionId:<{}>", sessionId);
            throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
        } else {
            UserSessionInfo userSessionInfo = JSON.parseObject(sessionInfo, UserSessionInfo.class);
            if (userId == null || !userId.equals(userSessionInfo.getUserId())) {
                rglog.error("用户未登录");
                throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
            }
            RedisUtil.onceExpire(sessionId, BompAppParamConstant.SESSION_EFFECTIVE_TIME);
            rglog.info("当前会话有效，重置会话有效时长。sessionId:<{}>,sessionExpiryTime:<{}>", sessionId, BompAppParamConstant.SESSION_EFFECTIVE_TIME);
            return userSessionInfo;
        }
    }
}
